#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
TqSdk Trader 主程序
稳健优雅的量化交易框架
"""

import asyncio
import signal
import sys
from typing import Dict, Any, Optional
from pathlib import Path

from config.config_manager import init_config, get_config
from utils.logger import init_logger, get_logger
from utils.exceptions import TqSdkTraderError
from core.api_manager import init_api_manager, get_api_manager
from core.trading_manager import init_trading_manager, get_trading_manager
from data.data_manager import init_market_data_manager, get_market_data_manager
from risk.risk_manager import init_risk_manager, get_risk_manager
from strategies.base_strategy import init_strategy_manager, get_strategy_manager
from strategies.dual_ma_strategy import create_dual_ma_strategy


class TqSdkTrader:
    """TqSdk Trader 主类"""

    def __init__(self, config_file: Optional[str] = None):
        self.logger = get_logger("TqSdkTrader")
        self.config = None
        self.config_file = config_file

        # 组件管理器
        self.api_manager = None
        self.trading_manager = None
        self.data_manager = None
        self.risk_manager = None
        self.strategy_manager = None

        # 运行状态
        self.is_running = False
        self.shutdown_event = asyncio.Event()

        self.logger.info("TqSdk Trader 初始化中...")

    async def initialize(self):
        """初始化所有组件"""
        try:
            # 1. 初始化配置
            self.logger.info("初始化配置管理器...")
            init_config(self.config_file)
            self.config = get_config()

            # 2. 初始化日志系统
            self.logger.info("初始化日志系统...")
            init_logger()

            # 3. 初始化API管理器
            self.logger.info("初始化API管理器...")
            self.api_manager = await init_api_manager()

            # 4. 初始化交易管理器
            self.logger.info("初始化交易管理器...")
            self.trading_manager = await init_trading_manager(self.api_manager)

            # 5. 初始化数据管理器
            self.logger.info("初始化数据管理器...")
            self.data_manager = await init_market_data_manager(self.api_manager)

            # 6. 初始化风险管理器
            self.logger.info("初始化风险管理器...")
            self.risk_manager = init_risk_manager()

            # 7. 初始化策略管理器
            self.logger.info("初始化策略管理器...")
            self.strategy_manager = init_strategy_manager()

            self.logger.info("所有组件初始化完成")

        except Exception as e:
            self.logger.error(f"初始化失败: {e}")
            raise TqSdkTraderError(f"初始化失败: {e}")

    async def start_trading(self):
        """开始交易"""
        try:
            self.logger.info("开始交易...")

            # 创建并启动策略
            await self._create_and_start_strategies()

            # 设置信号处理器
            self._setup_signal_handlers()

            self.is_running = True

            # 主交易循环
            await self._trading_loop()

        except Exception as e:
            self.logger.error(f"交易启动失败: {e}")
            raise TqSdkTraderError(f"交易启动失败: {e}")

    async def _create_and_start_strategies(self):
        """创建并启动策略"""
        try:
            # 创建双均线策略
            strategy = await create_dual_ma_strategy(
                symbol=self.config.strategy.symbol,
                config=self.config.strategy.__dict__
            )

            # 启动策略
            await self.strategy_manager.start_strategy(
                self.config.strategy.name,
                self.config.strategy.symbol
            )

            self.logger.info("策略创建并启动成功")

        except Exception as e:
            self.logger.error(f"创建策略失败: {e}")
            raise TqSdkTraderError(f"创建策略失败: {e}")

    def _setup_signal_handlers(self):
        """设置信号处理器"""
        def signal_handler(signum, frame):
            self.logger.info(f"收到信号 {signum}，准备关闭...")
            self.shutdown_event.set()

        # 处理SIGINT (Ctrl+C)
        signal.signal(signal.SIGINT, signal_handler)

        # 在Windows上也处理SIGTERM
        try:
            signal.signal(signal.SIGTERM, signal_handler)
        except OSError:
            pass  # Windows可能不支持SIGTERM

    async def _trading_loop(self):
        """主交易循环"""
        try:
            self.logger.info("进入主交易循环")

            while not self.shutdown_event.is_set():
                try:
                    # 等待API更新
                    await self.api_manager.wait_update()

                    # 更新订单状态
                    await self.trading_manager.update_orders_status()

                    # 清理已完成的订单
                    await self.trading_manager.cleanup_completed_orders()

                    # 定期检查系统状态
                    await self._periodic_check()

                    # 小延迟避免CPU占用过高
                    await asyncio.sleep(0.1)

                except Exception as e:
                    self.logger.error(f"交易循环异常: {e}")
                    await asyncio.sleep(1)  # 错误后稍等再继续

        except Exception as e:
            self.logger.error(f"交易循环严重异常: {e}")
        finally:
            self.logger.info("退出主交易循环")

    async def _periodic_check(self):
        """定期检查"""
        # 这里可以添加定期检查逻辑，比如：
        # - 检查连接状态
        # - 检查持仓状态
        # - 生成报告
        # - 检查风险指标
        pass

    async def stop_trading(self):
        """停止交易"""
        try:
            self.logger.info("开始停止交易...")

            self.is_running = False
            self.shutdown_event.set()

            # 停止所有策略
            if self.strategy_manager:
                await self.strategy_manager.cleanup_all()

            # 清理数据管理器
            if self.data_manager:
                await self.data_manager.cleanup()

            # 清理API连接
            if self.api_manager:
                await self.api_manager.cleanup()

            self.logger.info("交易停止完成")

        except Exception as e:
            self.logger.error(f"停止交易时出错: {e}")

    async def get_system_status(self) -> Dict[str, Any]:
        """获取系统状态"""
        try:
            status = {
                'is_running': self.is_running,
                'config_loaded': self.config is not None,
                'api_connected': self.api_manager.is_connected if self.api_manager else False,
                'trading_summary': {},
                'strategy_status': {},
                'risk_status': {},
                'system_health': 'unknown'
            }

            # 交易摘要
            if self.trading_manager:
                status['trading_summary'] = await self.trading_manager.get_trading_summary()

            # 策略状态
            if self.strategy_manager:
                status['strategy_status'] = await self.strategy_manager.get_all_strategies_status()

            # 风险状态
            if self.risk_manager:
                status['risk_status'] = self.risk_manager.get_risk_summary()

            # 系统健康状态
            status['system_health'] = self._calculate_system_health(status)

            return status

        except Exception as e:
            self.logger.error(f"获取系统状态失败: {e}")
            return {'error': str(e)}

    def _calculate_system_health(self, status: Dict[str, Any]) -> str:
        """计算系统健康状态"""
        try:
            health_score = 0
            total_checks = 0

            # 检查API连接
            if status.get('api_connected'):
                health_score += 1
            total_checks += 1

            # 检查策略运行状态
            strategy_status = status.get('strategy_status', {})
            if strategy_status and not any(s.get('status') == 'ERROR' for s in strategy_status.values()):
                health_score += 1
            total_checks += 1

            # 检查交易状态
            trading_summary = status.get('trading_summary', {})
            success_rate = trading_summary.get('success_rate', 0)
            if success_rate >= 0.8:  # 成功率80%以上
                health_score += 1
            elif success_rate >= 0.5:  # 成功率50%以上
                health_score += 0.5
            total_checks += 1

            # 计算健康度
            health_ratio = health_score / total_checks if total_checks > 0 else 0

            if health_ratio >= 0.8:
                return 'healthy'
            elif health_ratio >= 0.5:
                return 'warning'
            else:
                return 'critical'

        except Exception:
            return 'error'


async def main():
    """主函数"""
    logger = get_logger("Main")

    # 解析命令行参数
    config_file = None
    if len(sys.argv) > 1:
        config_file = sys.argv[1]

    trader = None

    try:
        # 创建交易器实例
        trader = TqSdkTrader(config_file)

        # 初始化
        await trader.initialize()

        # 显示系统状态
        status = await trader.get_system_status()
        logger.info(f"系统初始化完成，健康状态: {status.get('system_health', 'unknown')}")

        # 开始交易
        await trader.start_trading()

    except KeyboardInterrupt:
        logger.info("收到中断信号，正在优雅关闭...")
    except Exception as e:
        logger.error(f"程序运行异常: {e}")
        sys.exit(1)
    finally:
        if trader:
            await trader.stop_trading()
            logger.info("程序已安全退出")


def run_trader(config_file: Optional[str] = None):
    """运行交易器（同步接口）"""
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\n交易器已停止")
    except Exception as e:
        print(f"交易器运行失败: {e}")
        sys.exit(1)


if __name__ == "__main__":
    # 如果直接运行此文件
    run_trader()
